package com.qf.CompletableFuture;

import java.util.concurrent.*;

/**
 * 任务的串形化
 */
public class Demo03 {

    // 1.创建一个自己的线程池
    private static ThreadPoolExecutor executors = new ThreadPoolExecutor(
            5, // 核心线程池,线程池中至少有5个线程
            15, // 线程池中的最大线程数量
            3,  // 空闲线程回收的时间
            TimeUnit.SECONDS, // 时间单位
            new ArrayBlockingQueue(20), // 线程池中的线程已经最大了，剩下的引用压入队列等待空闲线程
            Executors.defaultThreadFactory(),  // 创建线程的默认工厂
            new ThreadPoolExecutor.AbortPolicy() // 拒绝策略，队列的长度满了以后执行的拒绝策略
    );

    public static void main(String[] args) throws ExecutionException, InterruptedException {


        // 1.两个任务串行，不依赖返回结构
//        CompletableFuture.runAsync(() -> {
//            System.out.println("任务1开始执行");
//        }, executors).thenRunAsync(() -> {
//            System.out.println("任务2开始执行");
//        }, executors);

        // 2.两个任务串行，任务2依赖任务1的返回结果，任务2没有返回结果
//        CompletableFuture.supplyAsync(() -> {
//            System.out.println("任务1开始执行计算结果，并返回");
//            return 10;
//        }).thenAcceptAsync((data) -> {
//            System.out.println("任务2开始执行，消费上一个任务的返回结果:" + data);
//        }, executors);

        // 3.两个任务串行，任务2依赖任务1的返回结果，任务2有返回结果
//        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
//            System.out.println("任务1开始执行计算结果，并返回");
//            return 10;
//        }).thenApplyAsync((data) -> {
//            System.out.println("任务2开始执行，消费上一个任务的返回结果:" + data);
//            return 100;
//        }, executors);
//        Integer integer = future.get();
//        System.out.println("任务2:" + integer);

        // 1、任务1计算结果
        CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("任务1计算");
            return 10;
        }, executors);

        // 2.任务2开始计算
        CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
            System.out.println("任务2计算");
            try {
                Thread.sleep(4000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return 20;
        }, executors);

        // 3.任务3需要任务1和2的结果，而且还有有返回值
        CompletableFuture<Integer> future3 = future2.thenCombineAsync(future1, (data1, data2) -> {
            return data1 + data2;
        }, executors);

        Integer integer = future3.get();
        System.out.println(integer);

    }
}

